package com.marion.study.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.marion.study.model.User;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

@Configuration
public class DataBaseConfig {

//    @Bean
//    @Primary
//    @ConfigurationProperties(prefix = "spring.datasource")
//    public DataSource druidDb() throws SQLException {
//        DruidDataSource dataSource = new DruidDataSource();
//        dataSource.setFilters("stat,wall");
//        return dataSource;
//    }

    @ConfigurationProperties(prefix = "user")
    @Bean("ur")
    public User user() {
        return new User();
    }

    /**
     * 主数据源
     */
    @SneakyThrows
    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.druid.write")
    public DataSource writeDruidDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setFilters("stat,wall");
        return dataSource;
    }

    /**
     * 从数据源
     */
    @SneakyThrows
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.druid.read")
    public DataSource readDruidDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setFilters("stat,wall");
        return dataSource;
    }

    /**
     * 主数据库JPA配置
     */
    @Primary
    @Bean("entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(writeDruidDataSource())
                .properties(getVendorProperties())
                .packages("com.marion.study.entity")
                .build();
    }

    /**
     * 从数据库JPA配置
     */
    @Bean
    public LocalContainerEntityManagerFactoryBean readEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(readDruidDataSource())
                .properties(getVendorProperties())
                .packages("com.marion.study.entity")
                .build();
    }

    /**
     * 公共属性配置
     */
    private Map<String, Object> getVendorProperties() {
        LinkedHashMap<String, Object> ret = new LinkedHashMap<>();
        ret.put("spring.jpa.hibernate.naming.physical-strategy", SpringPhysicalNamingStrategy.class.getName());
        return ret;
    }

    @Bean
    @Primary
    public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(Objects.requireNonNull(entityManagerFactory(builder).getObject()));
    }

    @Bean
    public PlatformTransactionManager readTransactionManager(@Qualifier("readEntityManagerFactory") LocalContainerEntityManagerFactoryBean readEntityManagerFactory) {
        return new JpaTransactionManager(Objects.requireNonNull(readEntityManagerFactory.getObject()));
    }

    /**
     * 扫描repository路径，如果不加@Repository不会生效，注意包路径是否正确，不正确Bean无法自动装配
     */
    @Primary
    @EnableJpaRepositories(basePackages = "com.marion.study.repo.write",
            entityManagerFactoryRef = "entityManagerFactory",
            transactionManagerRef = "transactionManager")
    public static class writeConfiguration {
    }

    @EnableJpaRepositories(basePackages = "com.marion.study.repo.read",
            entityManagerFactoryRef = "readEntityManagerFactory",
            transactionManagerRef = "readTransactionManager")
    public static class readConfiguration {
    }

    /*@Bean
    public ServletRegistrationBean druidServlet() {
        return new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
    }

    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }*/

}
